Skip to content

feat(ai): cost-aware routing + per-feature daily budget (Phase 12, AI-078 slice 4)#369

Merged
mrviduus merged 1 commit into
mainfrom
phase12-cost-budget
Jun 18, 2026
Merged

feat(ai): cost-aware routing + per-feature daily budget (Phase 12, AI-078 slice 4)#369
mrviduus merged 1 commit into
mainfrom
phase12-cost-budget

Conversation

@mrviduus

Copy link
Copy Markdown
Owner

Phase 12 (RLOps) — slice 4: cost-aware routing + daily budgets

Per-feature daily USD budgets — the DoD "cost-aware routing cuts spend" lever.

Spend tracking

RollingSpendTracker (singleton, Core ISpendTracker) accumulates per-feature spend in UTC-daily buckets as lock-free long micro-dollars (Interlocked.Add, Math.Round away-from-zero — no truncation drift). Lazy day rollover via injected TimeProvider. First touch each day seeds from llm_traces scaled by 1/sample-rate (the tracer samples — explain=0.1 in prod, so raw sum is 10× low) so a mid-day restart doesn't reset the budget to $0. Recording happens in the gateway (unsampled, exactly once per CompleteAsync/StreamAsync), not the sampled tracer.

Enforcement (ModelGateway)

Spend ≥ DailyUsd → mode fallback reroutes to a cheaper provider key (e.g. free local ollama); mode hardstop throws BudgetExceededException429. Budget logic can never break a live call — any tracker/config failure or unregistered fallback falls through to the true primary + logs. Shadow unaffected (still compares the TRUE primary, not the fallback); shadow spend doesn't count against the primary budget.

80% alert

Edge-triggered (once on crossing 0.8×budget, not per call), deduped per (feature, day), fire-and-forget via ResendEmailService (no-op if Resend:AdminAlertEmail empty), refires next day.

Admin

GET /admin/ai-quality/budgets + a "Daily budgets" section on the Summary tab — per-feature today-spend vs cap, color-coded % bar, mode, "in fallback" badge.

Scope / safety

Budgets OFF by default (Ai:Budgets empty) → zero behavior change until configured (Features:{feature}:{DailyUsd,Fallback,Mode}). No migration (in-memory + config). Multi-replica caveat: per-replica counters (lazy DB seed bounds drift; periodic re-seed = named follow-up); prod single-replica.

Verification

architect → backend + frontend (parallel, locked contract) → adversarial QA (SHIP): money-counting (round-once, record-exactly-once, shadow-excluded, seed-divide-not-multiply), edge-triggered alert (hammer-tested, no email storm), and never-break paths all verified; P2 (read-only endpoint seeding unbudgeted features) fixed. 761 unit tests green; admin tsc + build clean. Browser-check deferred to owner (needs a budget configured + admin JWT).

🤖 Generated with Claude Code

…e 12 slice 4)

Per-feature daily USD budgets with cost-aware enforcement.

- RollingSpendTracker (singleton, Core ISpendTracker): per-feature UTC-daily
  buckets, lock-free long micro-dollars (Interlocked.Add, Math.Round). Day
  rollover via TimeProvider. Lazy seed from llm_traces scaled by 1/sample-rate
  (traces are sampled; explain=0.1) so a mid-day restart doesn't reset to $0.
  Recording is in the gateway (unsampled, exactly once per call), not the
  sampled tracer.
- Gateway enforcement: spend >= DailyUsd -> mode fallback reroutes to a cheaper
  provider (e.g. free ollama); mode hardstop -> BudgetExceededException -> 429.
  NEVER breaks a live call (any failure -> true primary + log). Shadow
  unaffected (compares true primary); shadow spend not counted.
- 80% admin alert: edge-triggered, deduped per (feature, day), fire-and-forget
  via Resend (no-op if unset).
- Admin GET /budgets + Daily budgets section on Summary tab (reads tracker for
  budgeted features only).
- Budgets OFF by default (Ai:Budgets empty); no migration.

architect -> backend+frontend -> adversarial QA (SHIP; money-count/edge-alert/
never-break verified, P2 fixed). 761 unit tests green; admin tsc+build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mrviduus mrviduus merged commit 8a526f8 into main Jun 18, 2026
5 checks passed
@mrviduus mrviduus deleted the phase12-cost-budget branch June 18, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant